package com.ailot.cloud.base.security.config;


import com.ailot.cloud.base.security.authentication.filter.JwtAuthenticationTokenFilter;
import com.ailot.cloud.base.security.authentication.handler.JwtAccessDeniedHandler;
import com.ailot.cloud.base.security.utils.SecurityUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * 普通服务的安全配置
 */
@Configuration
@EnableConfigurationProperties({PermitUrlProperties.class})
public class SpringSecurityServiceConfigurer {


    private final PermitUrlProperties permitUrlProperties;

    public SpringSecurityServiceConfigurer(PermitUrlProperties permitUrlProperties) {
        this.permitUrlProperties = permitUrlProperties;
    }

    /**
     * Configuration using lambdas
     *
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    @ConditionalOnMissingBean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        permitUrlProperties.getUrls()
                .forEach(url -> registry.antMatchers(url).permitAll());
        // 内部服务调用不拦截
        registry.requestMatchers(request -> SecurityUtil.isInner(request))
                .permitAll().anyRequest().authenticated();
        http
                //禁用表单登录
                .formLogin().disable()
                // 关闭csrf
                .csrf((csrf) -> csrf.disable())
                //禁用session，JWT校验不需要session
                .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .exceptionHandling((exception) -> exception
                        // 未授权异常处理
                        .accessDeniedHandler(new JwtAccessDeniedHandler()));
        http.addFilterAfter(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter(permitUrlProperties);
    }


}
